using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Runtime.Serialization;

using KLATencor.CommonApp.Infrastructure.StateMachine;

using Syncfusion.Windows.Forms.Tools;
using Syncfusion.Windows.Forms.Diagram;
using Syncfusion.Windows.Forms.Diagram.Controls;

using StateMachine_Graphical_Editor.Shapes;
using StateMachine_Graphical_Editor.Utils;
using StateMachine_Graphical_Editor.Graphics_Rendering;

namespace StateMachine_Graphical_Editor.Forms
{
    /// <summary>
    /// Display all sub states of a selected parent state
    /// </summary>
    [Serializable]
    public partial class SubStatesForm : StatesForm
    {
        #region Members:
        
        private State triggeredSubState;

        #region Constants:

        private const string SUB_STATES_VIEW_TITLE = " - Sub States View";

        #endregion

        #endregion

        #region C'tors:

        public SubStatesForm()
        {
            InitializeComponent();
        }

        //for use in edit mode
        public SubStatesForm(State mainState, DisplayModes displayMode) 
            : this()
        {
            this.displayMode = displayMode;

            if (displayMode == DisplayModes.VIEW_MODE)
            {
                this.addEvent.Enabled = true;
                this.paletteGroupBar1.Visible = false;

                //disable right-click menues:
                this.contextMenuStripGState.Enabled = false;
                this.contextMenuStripGTransition.Enabled = false;
            }
            this.mainState = mainState;
            this.machine = mainState.StateMachine;
            this.machine.OnStateChange += new StateMachine.StateChange(onTransitionOccured);
            this.levelStatesCollection = mainState.Substates;

            //if new state with no substates, initiate from template
            this.Text = mainState.Name + SUB_STATES_VIEW_TITLE;
        }

        /// <summary>
        /// C'tor used when poping up during transition change event
        /// </summary>
        /// <param name="mainState">the state containing all states in this form</param>
        /// <param name="currentSubState">the state in the form that is the current in the transitions flow</param>
        /// <param name="displayMode">if form is loaded on run time or on design time</param>
        public SubStatesForm(State mainState, State currentSubState, DisplayModes displayMode) 
            : this(mainState, displayMode)
        { 
            this.triggeredSubState = currentSubState;
        }
        
        #endregion

        #region Getters/Setters:

        public State MainState
        {
            get { return mainState; }
        }

        #endregion

        #region Methods:

        /// <summary>
        /// The function which renders the state machine elements on the form.
        /// <para>Called when the OnLoad event occurs</para>
        /// </summary>
        public void drawSubStates()
        {
            this.initializer = GraphicsFactory.getFactory().createInitializer(mainState, this);

            if (initializer != null)
            {
                //present the list of all possible events
                updateEventsList();

                diagramElements = initializer.getGraphicalStateList();
                int index = 0;
                model.AppendChildren(diagramElements, out index);

                //if form raised because of a running machine paint as current the
                //initial state
                //but - if form raised from a cross hierarchy transition - this is not the case!!
                if (displayMode == DisplayModes.VIEW_MODE)
                {
                    if (triggeredSubState == null)
                    {
                        //set initial state as current
                        GState initial = initializer.getInitial();
                        initial.CurrentState = true;
                    }
                    else
                    {
                        //set the triggered state as current
                        GState current = initializer.getGraphicalState(triggeredSubState);
                        current.CurrentState = true;
                    }
                }
                //set a layout manager
                this.diagram.LayoutManager.UpdateLayout(null);
                this.diagram.UpdateView();

            }

            this.diagram.Controller.SelectionList.Clear();
        }

        protected override void updateEventsList()
        {
            //the ordinary events:
            base.updateEventsList();
            //add the root state's global events:
            foreach (Transition curTrans in mainState.Transitions)
            {
                string eventName = curTrans.EventName;
                MainEventsDropDownBox.Items.Add(eventName);
            }
            LaunchMainEventButton.Enabled = 
                MainEventsDropDownBox.Items.Count > 0 && 
                displayMode == DisplayModes.VIEW_MODE ? 
                true : false;
        }

        #endregion

        #region Main State Events Simulator Addition:

        protected void LaunchMainEvent_Click(object sender, EventArgs e)
        {
            try
            {
                /* will throw exception if machine isn't running: */
                string eventName = (String)this.MainEventsDropDownBox.SelectedItem;
                eventsQueue.Items.Add(eventName);
                machine.QueueEvent(new KLATencor.CommonApp.Infrastructure.StateMachine.StateMachineEvent(eventName));
            }
            catch (Exception SMexception)
            {
                MessageBox.Show(SMexception.Message);
            }
        }

        #endregion

        #region Form's loading and closing events:

        private void SubStatesForm_Load(object sender, EventArgs e)
        {
            if (MainForm.simulatorEnabled)
                this.eventsGroupBox.Visible = true; //default is false

            this.diagram.LayoutManager = new HierarchicLayoutManager(model, 0, 40, 80);

            drawSubStates();

        }

        private void SubStatesForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            //todo: update usage of new forms DS:
            //if (this.Equals(Utils.FormsManager.getManager().peek()))
            //    Utils.FormsManager.getManager().pop();
            //else
            //    MessageBox.Show("form is still in stack!");
        }

        #endregion

        #region StatesForm abstract Method Implementation:

        public override string getName()
        {
            return mainState.Name;
        }

        public override State getState()
        {
            return mainState;
        }

        public override void permitEventLaunching(bool isPermitted)
        {
            eventDropDownBox.SelectedItem = null;
            MainEventsDropDownBox.SelectedItem = null;
            addEvent.Enabled = isPermitted;
            LaunchMainEventButton.Enabled = isPermitted;
        }

        #endregion

        #region Serializable Implementation:

        public SubStatesForm(SerializationInfo info, StreamingContext str)
            : base(info, str)
        {
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext str)
        {
        }

        #endregion
    }
}